#include "std_async_ops.h"

int std_async_ops() {
    //!  1. std::promise<int>
    // promise将数据与future绑定, 为获取线程函数中的某个值提供便利. 在线程函数中为外面传进来的promise赋值
    std::promise<int> p;
    
    std::thread t([&p]() {
        // p.set_value(100);
        p.set_value_at_thread_exit(100);
    });
    t.join();             //! Notice: 不用join, f.get() 或阻塞等待, 但是必须join google test才通过 
    std::future<int> f1 = p.get_future();
    std::cout << f1.get() << std::endl;


    //! 2. std::packaged_task
    //  packaged_task 保存的是一个可调用对象, 可以异步执行， 然后在将来某处获取返回值
    std::packaged_task<int(int)> task([](int x) {
        return x * x;
    });
    std::thread t2(std::ref(task), 12);
    t2.join();
    std::future<int> f2 = task.get_future();
    std::cout << f2.get() << std::endl;

    //! future是不可拷贝的, 只能移动
    //! 如果想拷贝则需要std::shared_future.    其中任何一个拷贝的值改变都会影响到所有的拷贝



    //!  3. std::async
    //  std::async(std::launch::async || std::launch::deferred, f, args...);
    //    1. std::launch::async       调用时立马创建线程
    //    2. std::launch::deferred    延迟创建线程, 直到调用future的get或者wait时才创建
    std::future<int> f3 = std::async(std::launch::async, []() {
        return 100;
    });
    std::cout << f3.get() << std::endl;

    return 0;
}